<!DOCTYPE html>
<html lang="en" class="h-full" data-theme="light">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Paperless-AI Dashboard</title>
    <script src="https://cdn.tailwindcss.com/3.4.16"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.0/css/all.min.css">
    <link rel="stylesheet" href="css/dashboard.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"></script>
</head>
<body class="h-full">
    <button id="themeToggle" class="theme-toggle">
        <i class="fas fa-moon dark:fas fa-sun"></i>
    </button>

    <div class="layout-container">
        <button id="mobileMenuButton" class="mobile-menu-button">
            <i class="fas fa-bars"></i>
        </button>
        <!-- Sidebar -->
        <div id="sidebarOverlay" class="sidebar-overlay"></div>
        <aside class="sidebar">
            <div class="sidebar-header">
                <img src="/favicon.ico" class="no-invert" alt="Paperless AI Logo" style="height: 60px;">
                <h1 class="brand-title">Paperless-AI<small style="display: block;"><%= version %></small></h1>
            </div>

            <nav class="sidebar-nav">
                <ul>
                    <li>
                        <a href="/dashboard" class="sidebar-link">
                            <i class="fas fa-home"></i>
                            <span>Dashboard</span>
                        </a>
                    </li>
                    <li>
                        <a href="/manual" class="sidebar-link active">
                            <i class="fas fa-file-alt"></i>
                            <span>Manual</span>
                        </a>
                    </li>
                    <li>
                        <a href="/chat" class="sidebar-link">
                            <i class="fa-solid fa-comment"></i>
                            <span>Chat</span>
                        </a>
                    </li>
                    <li>
                        <a href="/rag" class="sidebar-link">
                            <i class="fa-solid fa-comment"></i>
                            <span>RAG Chat</span>
                        </a>
                    </li>                    
                    <li>
                        <a href="/playground" class="sidebar-link">
                            <i class="fa-solid fa-flask-vial"></i>
                            <span>Playground</span>
                        </a>
                    </li>
                    <li>
                        <a href="/history" class="sidebar-link">
                            <i class="fa-solid fa-clock-rotate-left"></i>
                            <span>History</span>
                        </a>
                    </li>
                    <li>
                        <a href="/settings" class="sidebar-link">
                            <i class="fas fa-cog"></i>
                            <span>Settings</span>
                        </a>
                    </li>
                    <li>
                        <a href="/logout" class="sidebar-link">
                            <i class="fa-solid fa-right-from-bracket"></i>
                            <span>Logout</span>
                        </a>
                    </li>
                </ul>
                <a href="https://github.com/clusterzx/paperless-ai" 
                class="github-button" 
                style="position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%);">
                <span class="star-button">
                    <svg class="star-icon" height="16" width="16" viewBox="0 0 16 16">
                        <path d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25z"></path>
                    </svg>
                    Star
                </span>
                <span id="starCount" class="star-count">1.2k</span>
            </a>
            <p style="position: absolute; bottom: 50px; left: 50%; transform: translateX(-50%); font-size: 10px; color: #555; text-align: center;">
                Please support us on GitHub
            </p>
            </nav>
        </aside>

        <!-- Main Content -->
        <main class="main-content">
            <div class="content-wrapper">
                <!-- Message Area -->
                <div id="messageArea" class="mb-6 hidden">
                    <!-- Messages will be inserted here -->
                </div>
        
                <!-- Document Selection -->
                <div class="material-card mb-6">
                    <h2 class="card-title">Select Document</h2>
                    <select id="documentSelect" class="w-full rounded-md border-border-color bg-bg-primary text-text-primary p-2 focus:border-accent-primary focus:ring-accent-primary">
                        <option value="">Choose a document...</option>
                    </select>
                </div>
        
                <!-- Main Grid -->
                <div class="card-grid">
                    <!-- Document Preview Card -->
                    <div class="material-card col-span-2">
                        <h2 class="card-title">Document Preview</h2>
                        <!-- Correspondent Info -->
                        <div id="correspondentInfo" class="stat-box mb-4 hidden">
                            <h3 class="text-sm font-medium">Correspondent:</h3>
                            <p id="correspondentName"></p>
                        </div>
                        <div id="titleInfo" class="stat-box mb-4 hidden">
                            <h3 class="text-sm font-medium">Title:</h3>
                            <p id="titleName"></p>
                        </div>
                        <div class="stat-box">
                            <div id="documentPreview" class="min-h-[600px] bg-bg-primary rounded border border-border-color p-4">
                                <div id="contentPreview" class="h-[600px] overflow-y-auto font-mono text-sm whitespace-pre-wrap"></div>
                            </div>
                        </div>
                    </div>
        
                    <!-- AI and Tags Section -->
                    <div class="col-span-2">
                        <!-- AI Analysis Card -->
                        <div class="material-card mb-6">
                            <h2 class="card-title">AI Analysis</h2>
                            <button id="analyzeBtn" 
                                    class="w-full flex justify-center items-center px-4 py-2 border border-border-color rounded-md shadow-sm text-sm font-medium text-text-primary bg-bg-primary hover:bg-hover-bg focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-accent-primary transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed" 
                                    disabled>
                                    <i class="fas fa-robot mr-2"></i>
                                    Analyze with AI
                            </button>
                            <button id="chatBtn" 
                                    class="mt-2 w-full flex justify-center items-center px-4 py-2 border border-border-color rounded-md shadow-sm text-sm font-medium text-text-primary bg-bg-primary hover:bg-hover-bg focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-accent-primary transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed" 
                                    disabled>
                                    <i class="fas fa-comment mr-2"></i>
                                    Chat with AI (Beta)
                            </button>
                            <div id="aiStatus" class="mt-4 hidden">
                                <div class="flex items-center">
                                    <div class="mr-3">
                                        <i class="fas fa-spinner fa-spin text-accent-primary"></i>
                                    </div>
                                    <div class="text-sm text-text-secondary">
                                        AI is analyzing the document...
                                    </div>
                                </div>
                            </div>
                        </div>
        
                        <!-- Tags Card -->
                        <div class="material-card">
                            <h2 class="card-title">Tags</h2>
                            <!-- AI Suggested Tags -->
                            <div class="mb-4">
                                <h3 class="text-sm font-medium text-text-secondary mb-2">AI Suggestions</h3>
                                <div id="suggestedTags" class="flex flex-wrap gap-2"></div>
                                <input type="hidden" id="tags" name="tags" value="">
                            </div>
        
                            <!-- Current Tags -->
                            <div class="mb-4">
                                <div class="flex justify-between items-center mb-2">
                                    <h3 class="text-sm font-medium text-text-secondary">Current Tags</h3>
                                    <button id="saveTagsBtn" 
                                            class="px-2 py-1 text-xs bg-green-600 text-white rounded hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 transition-all duration-200">
                                        Save Tags
                                    </button>
                                </div>
                                <div id="currentTags" class="flex flex-wrap gap-2"></div>
                            </div>
        
                            <!-- Add New Tag -->
                            <div>
                                <h3 class="text-sm font-medium text-text-secondary mb-2">Add New Tag</h3>
                                <div class="flex space-x-2">
                                    <select id="newTagSelect" class="flex-1 rounded-md border-border-color bg-bg-primary text-text-primary focus:border-accent-primary focus:ring-accent-primary">
                                        <option value="">Select a tag...</option>
                                    </select>
                                    <button id="addTagBtn" class="inline-flex items-center px-3 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-accent-primary hover:bg-accent-secondary focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-accent-primary transition-all duration-200">
                                        <i class="fas fa-plus"></i>
                                    </button>
                                    <input type="hidden" id="hiddenId" value="">
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </main>
    </div>
    <script>
// Global Variables
let availableTags = [];
let currentDocument = null;
let currentCorrespondent = null;
let isUpdating = false;

// Show message (error or success)
function showMessage(message, type = 'error') {
    const messageArea = document.getElementById('messageArea');
    const bgColor = type === 'error' ? 'bg-red-50' : 'bg-green-50';
    const textColor = type === 'error' ? 'text-red-700' : 'text-green-700';
    const borderColor = type === 'error' ? 'border-red-200' : 'border-green-200';
    const iconClass = type === 'error' ? 'fa-exclamation-circle text-red-400' : 'fa-check-circle text-green-400';

    messageArea.className = `mb-4 p-4 rounded-md ${bgColor} border ${borderColor}`;
    messageArea.innerHTML = `
        <div class="flex">
            <div class="flex-shrink-0">
                <i class="fas ${iconClass}"></i>
            </div>
            <div class="ml-3">
                <p class="text-sm ${textColor}">${message}</p>
            </div>
        </div>
    `;
    messageArea.classList.remove('hidden');

    setTimeout(() => {
        messageArea.classList.add('hidden');
    }, 5000);
}

// API Functions
async function fetchTags() {
    try {
        const response = await fetch('/manual/tags');
        if (!response.ok) throw new Error('Failed to fetch tags');
        const tags = await response.json();
        availableTags = tags;
        updateTagSelect(tags);
    } catch (error) {
        showMessage('Error loading tags: ' + error.message);
    }
}

async function fetchDocuments() {
    try {
        const response = await fetch('/manual/documents');
        if (!response.ok) throw new Error('Failed to fetch documents');
        const documents = await response.json();
        updateDocumentSelect(documents);
    } catch (error) {
        showMessage('Error loading documents: ' + error.message);
    }
}

// UI Update Functions
function updateDocumentSelect(documents) {
    if (!Array.isArray(documents)) return;
    const select = document.getElementById('documentSelect');
    select.innerHTML = '<option value="">Choose a document...</option>';
    documents.forEach(doc => {
        const option = document.createElement('option');
        option.value = doc.id;
        option.textContent = doc.title || doc.original_filename || `Document ${doc.id}`;
        select.appendChild(option);
    });
}

function updateTagSelect(tags) {
    if (!Array.isArray(tags)) return;
    const select = document.getElementById('newTagSelect');
    select.innerHTML = '<option value="">Select a tag...</option>';
    tags.forEach(tag => {
        const option = document.createElement('option');
        option.value = tag.id;
        option.textContent = tag.name;
        select.appendChild(option);
    });
}

function updateCorrespondentDisplay(correspondent) {
    const correspondentInfo = document.getElementById('correspondentInfo');
    const correspondentName = document.getElementById('correspondentName');
    
    if (correspondent) {
        correspondentName.textContent = correspondent.name || correspondent;
        correspondentInfo.classList.remove('hidden');
        currentCorrespondent = correspondent;
    } else {
        correspondentInfo.classList.add('hidden');
        currentCorrespondent = null;
    }
}

function updateTitleDisplay(title) {
    const titleInfo = document.getElementById('titleInfo');
    const titleName = document.getElementById('titleName');
    
    if (title) {
        titleName.textContent = title.name || title;
        titleInfo.classList.remove('hidden');
    } else {
        titleInfo.classList.add('hidden');
    }
}

function updateSuggestedTags(tags) {
    if (!Array.isArray(tags)) return;
    
    const suggestedTags = document.getElementById('suggestedTags');
    suggestedTags.innerHTML = '';
    
    tags.forEach(tag => {
        const tagElement = createTagElement(tag, 'blue', true);
        if (tagElement) {
            suggestedTags.appendChild(tagElement);
        }
    });
}

// Tag Management Functions
function createTagElement(tag, color = 'gray', isSuggested = false) {
    if (!tag) return null;

    // If tag is just an ID string/number, look up the full tag object in availableTags
    let fullTag = tag;
    if (typeof tag === 'string' || typeof tag === 'number') {
        fullTag = availableTags.find(t => t.id === parseInt(tag)) || { id: tag, name: tag };
    }

    const tagId = fullTag.id;
    const tagName = fullTag.name;

    const tagElement = document.createElement('span');
    tagElement.className = `inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-${color}-100 text-${color}-800`;
    tagElement.dataset.tagId = tagId;
    
    const nameSpan = document.createElement('span');
    nameSpan.textContent = tagName;
    tagElement.appendChild(nameSpan);

    const removeButton = document.createElement('button');
    removeButton.className = `ml-1 text-${color}-600 hover:text-${color}-800`;
    removeButton.innerHTML = '<i class="fas fa-times"></i>';
    removeButton.onclick = (e) => {
        e.preventDefault();
        e.stopPropagation();
        tagElement.remove();
        updateHiddenTagsInput(); // Update hidden input when tag is removed
    };
    tagElement.appendChild(removeButton);

    if (isSuggested) {
        const addButton = document.createElement('button');
        addButton.className = `ml-1 text-${color}-600 hover:text-${color}-800`;
        addButton.innerHTML = '<i class="fas fa-plus"></i>';
        addButton.onclick = (e) => {
            e.preventDefault();
            e.stopPropagation();
            const newTag = createTagElement(tag);
            if (newTag) {
                document.getElementById('currentTags').appendChild(newTag);
                updateHiddenTagsInput(); // Update hidden input when tag is added
                tagElement.remove();
            }
        };
        tagElement.appendChild(addButton);
    }

    return tagElement;
}

// Function to update the hidden input field with current tags
function updateHiddenTagsInput() {
    const currentTagElements = document.getElementById('currentTags').children;
    const tagIds = Array.from(currentTagElements)
        .map(el => el.dataset.tagId)
        .filter(id => id); // Filter out any undefined/null values

    // Update the hidden input field
    const hiddenInput = document.getElementById('tags');
    if (hiddenInput) {
        hiddenInput.value = tagIds.join(',');
    }
}

// Document Handling Functions
async function handleDocumentSelection(documentId) {
    if (!documentId) {
        document.getElementById('analyzeBtn').disabled = true;
        document.getElementById('chatBtn').disabled = true;
        document.getElementById('contentPreview').textContent = '';
        document.getElementById('currentTags').innerHTML = '';
        document.getElementById('suggestedTags').innerHTML = '';
        updateHiddenTagsInput(); // Clear hidden input when no document is selected
        return;
    }

    currentDocument = documentId;
    document.getElementById('analyzeBtn').disabled = false;
    document.getElementById('chatBtn').disabled = false;
    
    try {
        const response = await fetch(`/manual/preview/${documentId}`);
        if (!response.ok) throw new Error('Failed to fetch document content');
        const data = await response.json();
        
        if (!data.content) {
            throw new Error('Document content is missing');
        }
        
        document.getElementById('contentPreview').textContent = data.content || 'No content available';
        document.getElementById('hiddenId').value = data.id;
        
        document.getElementById('currentTags').innerHTML = '';
        document.getElementById('suggestedTags').innerHTML = '';

        if (data.tags && Array.isArray(data.tags)) {
            const currentTagsContainer = document.getElementById('currentTags');
            data.tags.forEach(tag => {
                const tagElement = createTagElement(tag, 'gray', false);
                if (tagElement) {
                    currentTagsContainer.appendChild(tagElement);
                }
            });
            updateHiddenTagsInput(); // Update hidden input with initial tags
        }

        updateCorrespondentDisplay(data.correspondent);
        updateTitleDisplay(data.title);
    } catch (error) {
        showMessage('Error loading document content: ' + error.message);
    }
}

// Analysis Functions
async function handleAnalysis() {
    if (!currentDocument) return;

    const aiStatus = document.getElementById('aiStatus');
    aiStatus.classList.remove('hidden');
    
    try {
        let content = document.getElementById('contentPreview').textContent;
        
        if (!content || content === 'No content available') {
            throw new Error('No document content available for analysis');
        }

        if(content.length > 50000) {
            content = content.substring(0, 50000);
        }

        const currentTagElements = document.getElementById('currentTags').children;
        const documentId = document.getElementById('hiddenId').value;
        const existingTags = Array.from(currentTagElements)
            .map(el => el.dataset.tagId)
            .filter(id => !isNaN(parseInt(id)))
            .map(id => parseInt(id));

        const response = await fetch('/manual/analyze', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                content: content,
                existingTags: existingTags,
                correspondent: currentCorrespondent,
                id: documentId
            })
        });

        if (!response.ok) {
            const errorData = await response.json();
            throw new Error(errorData.error || 'Analysis failed');
        }

        const result = await response.json();

        let suggestedTags = [];
        if (result.document && result.document.tags) {
            suggestedTags = result.document.tags.map(tag => ({
                id: tag,
                name: tag
            }));
        }

        updateSuggestedTags(suggestedTags);

        if (result.document && result.document.correspondent) {
            updateCorrespondentDisplay(result.document.correspondent);
            updateTitleDisplay(result.document.title);
        }
        showMessage('Analysis completed successfully', 'success');
    } catch (error) {
        showMessage('Error during analysis: ' + error.message);
        console.error('Analysis error:', error);
    } finally {
        aiStatus.classList.add('hidden');
    }
}

async function handleChat() {
    const documentId = document.getElementById('hiddenId').value;

    window.location.href= `/chat?open=${documentId}`
}

async function updateDocumentTags() {
    if (!currentDocument || isUpdating) return;

    isUpdating = true;
    try {
        const titleElement = document.getElementById('titleName');
        const tagsElement = document.getElementById('tags');
        
        // Add null checks
        const titleValue = titleElement ? titleElement.textContent : '';
        const tagIds = tagsElement && tagsElement.value ? tagsElement.value.split(',').filter(id => id) : [];

        const response = await fetch('/manual/updateDocument', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                documentId: currentDocument,
                tags: tagIds,
                correspondent: currentCorrespondent,
                title: titleValue
            })
        });

        if (!response.ok) {
            const errorData = await response.json();
            throw new Error(errorData.error || 'Failed to update document');
        }

        const result = await response.json();
        showMessage('Tags updated successfully', 'success');
    } catch (error) {
        showMessage('Error updating tags: ' + error.message);
        console.error('Update error:', error);
    } finally {
        isUpdating = false;
    }
}


// Initialize everything when the DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
    // Document selection
    document.getElementById('documentSelect').addEventListener('change', (e) => {
        handleDocumentSelection(e.target.value);
    });

    // Analyze button
    document.getElementById('analyzeBtn').addEventListener('click', handleAnalysis);

    // Chat button
    document.getElementById('chatBtn').addEventListener('click', handleChat);

    // Save tags button
    document.getElementById('saveTagsBtn').addEventListener('click', updateDocumentTags);

    // Add tag button
    document.getElementById('addTagBtn').addEventListener('click', (e) => {
        e.preventDefault();
        const select = document.getElementById('newTagSelect');
        const tagId = select.value;
        if (!tagId) return;

        const tag = availableTags.find(t => t.id === parseInt(tagId));
        if (tag) {
            const tagElement = createTagElement(tag);
            if (tagElement) {
                document.getElementById('currentTags').appendChild(tagElement);
                updateHiddenTagsInput(); // Update hidden input when new tag is added
                select.value = '';
            }
        }
    });

    // Initial data fetch
    fetchTags();
    fetchDocuments();

    const form = document.querySelector('form');
    if (form) {
        form.addEventListener('submit', function(e) {
            e.preventDefault();
            
            // Serialize form data excluding tags if none are present
            const formData = serializeFormWithoutEmptyTags(this);
            
            // Send form data using fetch
            fetch(this.action, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(formData)
            })
            .then(response => response.json())
            .then(data => {
                showMessage('Settings saved successfully', 'success');
            })
            .catch(error => {
                showMessage('Error saving settings: ' + error.message);
            });
        });
    }
});

function serializeFormWithoutEmptyTags(formElement) {
    const formData = new FormData(formElement);
    const currentTags = document.getElementById('currentTags');

    // If there are no visible tags, remove the tags field from form data
    if (!currentTags || currentTags.children.length === 0) {
        formData.delete('tags');
    }

    // Convert FormData to an object
    const object = {};
    formData.forEach((value, key) => {
        // Only include the tags field if we have visible tags
        if (key !== 'tags' || currentTags.children.length > 0) {
            object[key] = value;
        }
    });

return object;
}
    </script>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const mobileMenuButton = document.getElementById('mobileMenuButton');
            const sidebar = document.querySelector('.sidebar');
            const sidebarOverlay = document.getElementById('sidebarOverlay');
            
            function toggleSidebar(event) {
                event.stopPropagation(); // Prevent event bubbling
                sidebar.classList.toggle('active');
                sidebarOverlay.classList.toggle('active');
                
                // Toggle menu icon
                const icon = mobileMenuButton.querySelector('i');
                if (sidebar.classList.contains('active')) {
                    icon.classList.remove('fa-bars');
                    icon.classList.add('fa-times');
                } else {
                    icon.classList.remove('fa-times');
                    icon.classList.add('fa-bars');
                }
            }

            // Toggle sidebar when clicking the menu button
            mobileMenuButton.addEventListener('click', toggleSidebar);

            // Close sidebar when clicking the overlay
            sidebarOverlay.addEventListener('click', function(event) {
                event.stopPropagation(); // Prevent event bubbling
                if (sidebar.classList.contains('active')) {
                    toggleSidebar(event);
                }
            });

            // Prevent sidebar from closing when clicking inside it
            sidebar.addEventListener('click', function(event) {
                event.stopPropagation();
            });

            // Handle links in sidebar
            const sidebarLinks = document.querySelectorAll('.sidebar-link');
            sidebarLinks.forEach(link => {
                link.addEventListener('click', function(event) {
                    // Don't prevent default here to allow navigation
                    event.stopPropagation();
                });
            });
        });
    </script>
    <script>
        // get github stars count from repo
        async function getStarsCount() {
            try {
                const response = await fetch('https://api.github.com/repos/clusterzx/paperless-ai');
                if (!response.ok) throw new Error('Failed to fetch repo info');
                
                const data = await response.json();
                document.getElementById('starCount').textContent = data.stargazers_count.toLocaleString();
            } catch (error) {
                console.error('Failed to fetch stars count:', error);
            }
        }
        document.addEventListener('DOMContentLoaded', function() {
            getStarsCount();
        });
    </script>
    <script src="js/dashboard.js"></script>
</body>
</html>